package de.preamp.clients.java.playlist.ui; // NOPMD

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.AbstractAction;
import javax.swing.DropMode;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import de.preamp.clients.java.lib.ui.DBItemCellRenderer;
import de.preamp.clients.java.playlist.Playlist;
import de.preamp.clients.java.utils.ImageLoader;

/**
 * @author André Stannek
 * @version 2011-06-11
 */
public class PlaylistManagerUI extends JPanel // NOPMD
{ // NOPMD
    /**
     * generated UID.
     */
    private static final long serialVersionUID = 4949816233829148453L;

    /**
     * 
     */
    private transient JList currentPlaylistUI;

    /**
     * 
     */
    private transient JList playlistsUI;

    /**
     * 
     */
    private transient JButton newPlaylistButton;

    /**
     * 
     */
    private transient JLabel playlistTitle;

    /**
     * 
     */
    private final PlaylistManagerBean bean;

    /**
     * 
     */
    public PlaylistManagerUI()
    {
	super();
	final ApplicationContext context =
		new FileSystemXmlApplicationContext(
			"src/main/resources/META-INF/applicationContext.xml");
	bean = (PlaylistManagerBean) context.getBean("playlistManagerBean");
	init();
    }

    /**
     * 
     */
    private void init()
    {
	playlistTitle = new JLabel();
	newPlaylistButton =
		new JButton(new ImageIcon(
			ImageLoader.getImageURL("document-new.png")));

	playlistsUI = new JList(bean.getPlaylistManager());

	final Playlist currentPlaylist =
		bean.getPlaylistManager().getSelectedPlaylist();

	currentPlaylistUI = new JList(currentPlaylist);

	currentPlaylistUI.addListSelectionListener(currentPlaylist);
	currentPlaylistUI.setCellRenderer(new DBItemCellRenderer());
	currentPlaylistUI.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	currentPlaylistUI.setDragEnabled(true);
	currentPlaylistUI.setTransferHandler(new PlaylistTransferHandler());
	currentPlaylistUI.setDropMode(DropMode.INSERT);

	playlistTitle.setText(currentPlaylist.getName());

	initPlaylistsUI();
	initUI();
    }

    /**
     * 
     */
    private void initPlaylistsUI() // NOPMD
    {
	playlistsUI.setCellRenderer(new PlaylistCellRenderer());
	playlistsUI.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	playlistsUI.addListSelectionListener(new ListSelectionListener()
	{
	    @Override
	    public void valueChanged(final ListSelectionEvent event)
	    {
		if (!event.getValueIsAdjusting())
		{
		    bean.getPlaylistManager().valueChanged(event);
		    changePlaylist();
		}
	    }
	});
	playlistsUI.addKeyListener(new KeyAdapter()
	{
	    private int key = -1;

	    @Override
	    public void keyReleased(final KeyEvent event)
	    {
		if (event.getKeyCode() == key)
		{
		    if (key == KeyEvent.VK_DELETE)
		    {
			bean.getPlaylistManager()
				.removePlaylist(
					bean.getPlaylistManager()
						.getSelectedPlaylist());
			changePlaylist();
		    }
		    else if (key == KeyEvent.VK_DOWN)
		    {
			changePlaylist();
		    }
		    else if (key == KeyEvent.VK_UP)
		    {
			changePlaylist();
		    }
		}
		key = -1;
	    }

	    @Override
	    public void keyPressed(final KeyEvent event)
	    {
		key = event.getKeyCode();
	    }
	});

	playlistsUI.addMouseListener(new MouseAdapter()
	{
	    @Override
	    public void mouseClicked(final MouseEvent event)
	    {
		if (event.getButton() == MouseEvent.BUTTON3)
		{
		    final int index =
			    playlistsUI.locationToIndex(event.getPoint());
		    final Object selected =
			    playlistsUI.getModel().getElementAt(index);
		    if (selected instanceof Playlist)
		    {
			final PlaylistManagerContextMenuUI menu =
				new PlaylistManagerContextMenuUI(
					(Playlist) selected);
			menu.show(event.getComponent(), event.getX(),
				event.getY());
		    }
		}
	    }
	});
    }

    /**
     * 
     */
    private void changePlaylist()
    {
	currentPlaylistUI.setModel(bean.getPlaylistManager()
		.getSelectedPlaylist());
	playlistTitle.setText(bean.getPlaylistManager().getSelectedPlaylist()
		.getName());
    }

    /**
     * 
     */
    private void initUI()
    {
	// Layout for overall Pane
	this.setLayout(new BorderLayout());

	// Split Pane with Playlists on top and current Playlist on bottom
	final JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
	splitPane.setOneTouchExpandable(true);
	splitPane.setDividerLocation(100);

	// top pane for split panel
	final JPanel topPane = new JPanel(new BorderLayout());
	final JPanel playlistHeader =
		new JPanel(new FlowLayout(FlowLayout.RIGHT));
	playlistHeader.add(new JLabel("Playlists"));
	newPlaylistButton.setPreferredSize(new Dimension(16, 16));
	newPlaylistButton.setToolTipText("Create a new playlist");
	newPlaylistButton.addActionListener(new ActionListener()
	{
	    @Override
	    public void actionPerformed(final ActionEvent event)
	    {
		new NewPlaylistDialog();
	    }
	});
	playlistHeader.add(newPlaylistButton);
	topPane.add(playlistHeader, BorderLayout.NORTH);
	topPane.add(new JScrollPane(playlistsUI), BorderLayout.CENTER);

	// bottom pane for split panel
	final JPanel bottomPane = new JPanel(new BorderLayout());
	bottomPane.add(playlistTitle, BorderLayout.NORTH);
	bottomPane.add(new JScrollPane(currentPlaylistUI), BorderLayout.CENTER);

	// set components for split pane
	splitPane.setTopComponent(topPane);
	splitPane.setBottomComponent(bottomPane);
	this.add(splitPane, BorderLayout.CENTER);

	this.add(topPane, BorderLayout.NORTH);

	this.setMinimumSize(new Dimension(100, 100));
    }

    /**
     * @author André Stannek
     */
    private class NewPlaylistDialog extends JDialog
    {
	/**
	 * 
	 */
	private static final long serialVersionUID = -3671182287592400823L;

	/**
	 * 
	 */
	private final transient JButton createButton, cancelButton;

	/**
	 * 
	 */
	private final transient JTextField playlistName;

	/**
	 * @param creator
	 */
	public NewPlaylistDialog()
	{
	    super();
	    this.setModal(true);

	    playlistName = new JTextField();
	    final Dimension buttonSize = new Dimension(100, 24);

	    createButton = new JButton("Create");
	    createButton.setPreferredSize(buttonSize);
	    createButton.addActionListener(new ActionListener()
	    {
		@Override
		public void actionPerformed(final ActionEvent event)
		{
		    bean.getPlaylistManager().newPlaylist(
			    playlistName.getText());
		    dispose();
		}
	    });

	    cancelButton = new JButton("Cancel");
	    cancelButton.setPreferredSize(buttonSize);
	    cancelButton.addActionListener(new ActionListener()
	    {
		@Override
		public void actionPerformed(final ActionEvent event)
		{
		    dispose();
		}
	    });

	    final JPanel contentPane = new JPanel(new GridLayout(3, 1));

	    contentPane.add(new JLabel(
		    "Please enter a name for the new playlist:"));
	    contentPane.add(playlistName);

	    final JPanel buttonPane = new JPanel(new FlowLayout());
	    buttonPane.add(createButton);
	    buttonPane.add(cancelButton);
	    contentPane.add(buttonPane);

	    this.setContentPane(contentPane);

	    this.setSize(new Dimension(350, 115));
	    this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
	    this.setVisible(true);
	}
    }

    /**
     * @author André Stannek
     * @version 2010-01-24
     */
    private class PlaylistManagerContextMenuUI extends JPopupMenu
    {
	/**
	 * 
	 */
	private static final long serialVersionUID = -5876725505527539776L;

	/**
	 * Constructor creating a new context menu with a selected playlist.
	 * 
	 * @param selectedPlaylist
	 *            the playlist that is selected
	 */
	public PlaylistManagerContextMenuUI(final Playlist selectedPlaylist)
	{
	    super();
	    this.add(new DeleteAction(selectedPlaylist));
	}

	/**
	 * @author André Stannek
	 * @version 2010-01-24
	 */
	private class DeleteAction extends AbstractAction
	{

	    /**
	     * 
	     */
	    private static final long serialVersionUID = -4667884756152554336L;

	    /**
	     * 
	     */
	    private final transient Playlist playlist;

	    /**
	     * This action deletes a selected playlist.
	     * 
	     * @param selectedPlaylist
	     *            the playlist that is selected
	     */
	    public DeleteAction(final Playlist selectedPlaylist)
	    {
		super("delete playlist");
		playlist = selectedPlaylist;
	    }

	    @Override
	    public void actionPerformed(final ActionEvent event)
	    {
		bean.getPlaylistManager().removePlaylist(playlist);
	    }

	}
    }
}
